package NWish.properties.materials
{
	public class DefaultMaterialBaseProperties extends MaterialBaseProperties
	{
		public function DefaultMaterialBaseProperties(parent,materialPropertiesTypes)
		{
			super(parent,materialPropertiesTypes);
			
			var _keys
			= 
				['alphaThreshold'
				,'gloss'
				,'ambient'
				,'specular'
				,'ambientColor'
				,'specularColor'
				
				//,new ColorTransformProperties()
				
				,new TextureProperties(parent,'normalMap')
				,new TextureProperties(parent,'specularMap')
				,new TextureProperties(parent,'glossMap')
				
				,new AddRenderMethod(parent)
				,new MethodProperties('diffuseMethod')
				,new MethodProperties('specularMethod')
				,new MethodProperties('ambientMethod')
				,new MethodProperties('shadowMethod')
				,new ExtraMethodProperties('fogMethod')
				
				];
			addPropertieKeys('Default',_keys);
		}
	}
}


import NWish.Interface.ILogger;

import NWish.json.OrderDict;
import NWish.properties.Properties;
import NWish.properties.materials.MaterialMethod.*;

import away3d.materials.DefaultMaterialBase;
import away3d.materials.methods.*;

import flash.geom.ColorTransform;


class AddRenderMethod
{
	static private var _renderMethods =
		['BasicDiffuseMethod' 
		,'BasicSpecularMethod'
		,'BasicAmbientMethod'
		,'CelDiffuseMethod'
		,'CelSpecularMethod'
		,'EnvMapDiffuseMethod'
		,'EnvMapAmbientMethod'
		,'EnvMapMethod'
		,'FogMethod'
		,'FresnelSpecularMethod'
		,'ProjectiveTextureMethod'
		,'RimLightMethod'
		,'SoftShadowMapMethod'
		,'HardShadowMapMethod'
		,'SlowFilteredShadowMapMethod'
		,'SubsurfaceScatteringDiffuseMethod'
		,'TerrainDiffuseMethod'
		];
	
	private var _parent;
	
	public function AddRenderMethod(parent)
	{
		_parent = parent;
	}
	
	public function propertiesToDict(mat:DefaultMaterialBase,dict:OrderDict,read_only,saving = false)
	{
		if(read_only == false)
		{
			if(saving == false)
			{
				dict.push('add Render Method','');
				dict.push(Properties.readMark + 'Render Methods',_renderMethods);
			}
		}
	}
	
	public function create(arm,mat:DefaultMaterialBase)
	{
		switch(arm)
		{
			case '':
				break;
			case 'BasicDiffuseMethod':
				mat.diffuseMethod = new BasicDiffuseMethod();
				break;
			case 'BasicSpecularMethod':
				mat.specularMethod = new BasicSpecularMethod();
				break;
			case 'BasicAmbientMethod':
				mat.ambientMethod = new BasicAmbientMethod();
				break;
			case 'CelDiffuseMethod':
				mat.diffuseMethod = new CelDiffuseMethod();
				break;
			case 'CelSpecularMethod':
				mat.specularMethod = new CelSpecularMethod();
				break;
			case 'EnvMapDiffuseMethod':
				//mat.diffuseMethod = new EnvMapDiffuseMethod();
				ILogger.log('todo ' + arm + '  ...');
				break;
			case 'EnvMapAmbientMethod':
				//mat.ambientMethod = new EnvMapAmbientMethod();
				ILogger.log('todo ' + arm + '  ...');
				break;
			case 'EnvMapMethod':
				ILogger.log('todo ' + arm + '  ...');
				break;
			case 'FogMethod':
				if(mat.extra == null)
					mat.extra = new Object();
				mat.extra.fogMethod = new FogMethod(500)
				mat.addMethod(mat.extra.fogMethod);
				break;
			case 'FresnelSpecularMethod':
				mat.specularMethod = new FresnelSpecularMethod();
				break;
			case 'ProjectiveTextureMethod':
				ILogger.log('todo ' + arm + '  ...');
				break;
			case 'RimLightMethod':
				ILogger.log('todo ' + arm + '  ...');
				break;
			case 'SoftShadowMapMethod':
				var ls = _parent.getPlugin('Away3d').lights;
				if(ls == null)
				{
					ILogger.log('please create a light first!');
					return;
				}
				mat.shadowMethod = new SoftShadowMapMethod(ls[0]);
				break;
			case 'HardShadowMapMethod':
				var ls = _parent.getPlugin('Away3d').lights;
				if(ls == null)
				{
					ILogger.log('please create a light first!');
					return;
				}
				mat.shadowMethod = new HardShadowMapMethod(ls[0]);
				break;
			/*case 'SlowFilteredShadowMapMethod':
				var ls = _parent.getPlugin('Away3d').lights;
				if(ls == null)
				{
					ILogger.log('please create a light first!');
					return;
				}
				mat.shadowMethod = new SlowFilteredShadowMapMethod(ls[0]);
				break;*/
			case 'SubsurfaceScatteringDiffuseMethod':
				//mat.diffuseMethod = new SubsurfaceScatteringDiffuseMethod();
				ILogger.log('todo ' + arm + '  ...');
				break;
			case 'TerrainDiffuseMethod':
				mat.diffuseMethod = new TerrainDiffuseMethod();
				break;
			default:
				ILogger.log('can not find render method ' + arm);
				break;
		}
	}
	public function dictToProperties(dict,mat:DefaultMaterialBase,scene,isloading)
	{
		var arm = dict['add Render Method'];
		
		if(arm)
			create(arm,mat);
		else if(isloading)
		{
			for each(var rm in _renderMethods)
			{
				var rmt = dict[rm]
				if(rmt)
					create(rm,mat);
			}
		}
	}
	
}

class MethodProperties
{
	static private var _renderMethods = 
		[new CelDiffuseMethodProperties()
		,new CelSpecularMethodProperties()
		,new FogMethodProperties()
		,new FresnelSpecularMethodProperties()
		//,new EnvMapAmbientMethodProperties()
		//,new EnvMapDiffuseMethodProperties()
		//,new EnvMapMethodProperties()
		//,new RimLightMethodProperties()
		//,new SubsurfaceScatteringDiffuseMethodProperties()
		,new HardShadowMapMethodProperties()
		//,new SlowFilteredShadowMapMethodProperties()
		,new FilteredShadowMapMethodProperties()
		,new FilteredShadowMapMethodProperties()
		];
	
	protected var _renderMethod;
	
	public function MethodProperties(renderMethod)
	{
		_renderMethod = renderMethod;
	}
	
	protected function getMatMethod(mat:DefaultMaterialBase)
	{
		return mat[_renderMethod];
	}
	
	public function propertiesToDict(mat:DefaultMaterialBase,dict:OrderDict,read_only,saving = false)
	{
		var class_str:String = getMatMethod(mat) + '';
		if(class_str.search('BasicDiffuseMethod') != -1)
			return;
		if(class_str.search('BasicSpecularMethod') != -1)
			return;
		if(class_str.search('BasicAmbientMethod') != -1)
			return;
		
		if(read_only == false)
		{
			if(saving == false)
			{
			}
			
			for each(var rm in _renderMethods)
			{
				if(getMatMethod(mat) is rm.type)
				{
					var sub = new OrderDict();
					dict.push(rm.toString(),sub);
					rm.propertiesToDict(getMatMethod(mat),sub,read_only,saving);
				}
			}
		}
		else
		{
			for each(var rm in _renderMethods)
			{
				if(getMatMethod(mat) is rm.type)
				{
					var sub = dict.get(rm.toString());
					rm.propertiesToDict(getMatMethod(mat),sub);
				}
			}
		}
	}
	
	public function dictToProperties(dict,mat:DefaultMaterialBase,scene,isloading)
	{
		for each(var rm in _renderMethods)
		{
			var method = dict[rm.toString()];
			if(method)
			{
				if(getMatMethod(mat) is rm.type)
					rm.dictToProperties(method,getMatMethod(mat),scene,isloading);
			}
		}
	}
	
}


class ExtraMethodProperties extends MethodProperties
{
	
	public function ExtraMethodProperties(renderMethod)
	{
		super(renderMethod);
	}
	
	override protected function getMatMethod(mat:DefaultMaterialBase)
	{
		if(mat.extra == null)
			return null;
		
		return mat.extra[_renderMethod];
	}
}

/*
class ColorTransformProperties
{
	public function ColorTransformProperties()
	{
	}
	
	public function propertiesToDict(mat,dict:OrderDict,read_only,saving = false)
	{
		if(read_only == false)
		{
			if(saving == false)
			{
			}
			
			if(mat.colorTransform)
				dict.push('colorTransform',mat.colorTransform.color);
			else
				dict.push('colorTransform',mat.colorTransform);
		}
		else
		{
		}
	}
	
	public function dictToProperties(dict,mat,scene,isloading)
	{
		var color = dict['colorTransform'];

		if(color)
		{
			if(mat.colorTransform == null)
				mat.colorTransform = new ColorTransform();
			
			mat.colorTransform.color = color;
		}
		else
			mat.colorTransform = null;
	}
	
}

*/

